#include <webx/menu.h>

class SendMail : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(SendMail)

int SendMail::process()
{
	static string queuename = stdx::format("%s:sendmail_queue", GetCurrentUser());

	param_string(flag);
	param_string(mail);

	if (flag == "C") return simpleResponse(Sharemem().open(queuename) ? XG_OK : XG_NOTFOUND);

	stdx::tolower(mail);

	auto sendMail = [&](const string& id, const string& msg){
		int res;
		MsgQueue mq;

		if (msg.length() > 0 && mq.open(queuename) && mq.push(msg.c_str(), msg.length()))
		{
			LogTrace(eINF, "send mail[%s] success[%d]", id.c_str(), res = msg.length());
		}
		else
		{
			LogTrace(eERR, "send mail[%s] failed[%d]", id.c_str(), res = mq.canUse() ? XG_SYSBUSY : XG_SYSERR);
		}

		return res;
	};
	
	int res = XG_PARAMERR;
	int timeout = 10 * 60;

	if (flag == "R" || flag == "P" || flag == "L" || flag == "T")
	{
		time_t tm = time(NULL);
		string id = app->getSequence();
		string sid = webx::GetSessionId(request);

		res = XG_OK;

		if (flag == "T")
		{
			checkSession(sid);
			checkSystemRight();

			param_string(title);
			param_string(content);
			param_string(grouplist);

			if (title.empty() || content.empty() || title.length() > 128 || content.length() > 1024 * 1024) return simpleResponse(XG_PARAMERR);

			JsonElement data;

			data["id"] = id;
			data["user"] = mail;
			data["title"] = title;
			data["content"] = content;
			data["grouplist"] = grouplist;

			res = sendMail(id, data.toString());
		}
		else if (webx::IsMailString(mail))
		{
			int count = 0;
			const char* filepath = "res/etc/login.json";

			if (flag == "P") filepath = "res/etc/password.json";
			if (flag == "R") filepath = "res/etc/register.json";
			
			SmartBuffer content;
			const CgiMapData cfg = app->getCgiMapData(filepath);

			if (cfg.url.empty() || app->getFileContent(cfg.url, content) <= 0)
			{
				LogTrace(eERR, "json file[%s] not found", filepath);

				res = XG_SYSERR;
			}

			if (res >= 0)
			{
				try
				{
					checkSession(sid);

					string str = session->get("TIME");
					
					if (str.length() > 0 && stdx::atol(str.c_str()) + 60 > tm)
					{
						res = XG_AUTHFAIL;
					}
					else
					{
						str = session->get("COUNT");
						
						if (str.length() > 0 && IsNumberString(str.c_str()))
						{
							if ((count = stdx::atoi(str.c_str())) >= 10)
							{
								res = XG_AUTHFAIL;
							}
						}
					}
				}
				catch(Exception e)
				{
					if (webx::GetSession(mail)) res = XG_AUTHFAIL;
				}
			}

			if (res >= 0)
			{
				string sqlcmd;
				sp<DBConnect> dbconn = webx::GetDBConnect();

				stdx::format(sqlcmd, "SELECT USER FROM T_XG_USER WHERE MAIL='%s'", mail.c_str());
				
				sp<QueryResult> rs = dbconn->query(sqlcmd);

				if (!rs)
				{
					res = XG_SYSERR;
				}
				else if (!rs->next())
				{
					if (flag == "P")
					{
						LogTrace(eIMP, "mail[%s] not registered", mail.c_str());

						res = XG_NOTFOUND;
					}
				}
				else
				{
					if (flag == "R")
					{
						LogTrace(eIMP, "mail[%s] registered", mail.c_str());

						res = XG_DUPLICATE;
					}
				}
				
				if (res >= 0)
				{
					if (!session)
					{
						while (true)
						{
							sid = flag + DateTime::GetBizId() + id;
							sid = MD5GetEncodeString(sid.c_str(), sid.length(), true).val;

							session = webx::GetSession(sid);

							if (!session)
							{
								session = webx::GetSession(sid, timeout);

								break;
							}
						}						
					}

					JsonElement data(content.str());

					if (data.isNull() || data["content"].isNull() || data["content"].asString().empty())
					{
						LogTrace(eERR, "parse json file[%s] failed", cfg.url.c_str());
						
						return simpleResponse(XG_DATAERR);
					}

					string msg;
					string code;
					string link;
					string content;

					stdx::format(code, "%06d", (int)((clock() + rand()) % 1000000));

					if (flag == "P" || flag == "R")
					{
						link = webx::GetParameter("WEBSITE");
					}
					else
					{
						char buffer[4096] = {0};
						string text = HEXEncode(mail.c_str(), mail.length(), buffer);

						link = webx::GetParameter("WEBSITE") + "/index?session=" + text + "&code=" + code;
					}

					stdx::format(content, data["content"].asString().c_str(), code.c_str(), timeout / 60, link.c_str());
					
					data["id"] = id;
					data["user"] = mail;
					data["content"] = content;
					data["deadline"] = (int)(tm + timeout);

					if ((res = sendMail(id, data.toString())) < 0) return simpleResponse(res);

					session->set("COUNT", stdx::str(count + 1));
					session->set("TIME", stdx::str(tm));
					session->set("MAIL", mail);
					session->set("CODE", code);

					webx::SetSessionId(response, sid);
					webx::GetSession(mail, 30);
				}
			}
		}
		else
		{
			res = XG_PARAMERR;
		}
	}

	json["code"] = res;
	out << json;
	
	return XG_OK;
}